Skip to content

Release v0.0.17#18

Merged
akatz-ai merged 100 commits intomainfrom
dev
Feb 3, 2026
Merged

Release v0.0.17#18
akatz-ai merged 100 commits intomainfrom
dev

Conversation

@akatz-ai
Copy link
Copy Markdown
Member

@akatz-ai akatz-ai commented Feb 2, 2026

Summary

Major feature release spanning HuggingFace integration, workflow dependency management, environment details, git push/pull previews, and testing infrastructure.

Features

  • HuggingFace Integration — Search, file browser, repo info/subdirectory endpoints, token management modal, auto-detect download destinations from HF file paths
  • Missing Resources Popup — Intercept workflow loads to detect missing nodes/models, resolution flow with install/download actions, session-based suppression
  • Workflow Analysis — New /workflow/analyze-json endpoint, download intent handling, is-saved workflow detection
  • Environment Details — Per-environment detail API endpoint, collapsible workflow/node/model lists, creation date display
  • Push/Pull Modals — Commit preview for outgoing pushes and incoming pulls
  • Branch Detail Modal — Improved branch management UX
  • Model Download Modal — Unified download modal shell with HuggingFace tab, CivitAI placeholder, direct URL tab
  • Keyboard Shortcuts — Configurable shortcuts for panel and commit popover
  • Orchestrator Crash Retry — General crash retry with configurable delay
  • Show All Modal — Modal for viewing all missing resources at once

Fixes

  • Reset panel tab to status on browser refresh
  • Suppress ComfyUI built-in missing nodes/models popups
  • WebSocket event listener fixes for install completion
  • UUID fallback for non-secure contexts
  • Race condition fix in download destination auto-detect
  • Unicode icon replaced with inline SVG in PushModal

Infrastructure

  • E2E testing with Playwright (global setup/teardown, fixture infrastructure)
  • Harness scripts for workspace/browser/ComfyUI management
  • Workspace template fixtures (tarball-based)
  • Beads issue tracking integration
  • Version bump to 0.0.17, comfygit-core pinned to 0.3.13

Test plan

  • Run uv run pytest testing/ -v — verify all unit/integration tests pass
  • Build frontend cd frontend && bun run build — verify no build errors
  • Manual smoke test: open panel, navigate all sections
  • Verify HuggingFace search and file browser with valid token
  • Verify push/pull modals show commit previews
  • Verify missing resources popup triggers on workflow with missing deps

When a workflow has models with embedded download URLs (property_download_intent
from node properties.models), clicking "Apply Resolution" now writes them to
pyproject.toml before starting downloads. This allows _finalize_download to
find and update them from "unresolved" to "resolved" when download completes.

Previously, these models only existed in the ResolutionResult object and were
never persisted, causing the workflow to still show "missing models" until
user saved (Ctrl+S) triggering re-analysis.

- Add new block in apply_resolution to write property_download_intent models
- Uses expected_categories from core library's node analysis for category
- Respects user choices (skip/cancel/optional) before writing
- Avoids duplicates by checking existing models in pyproject
Register beforeConfigureGraph and afterConfigureGraph hooks in the
ComfyGit extension to capture workflow data when workflows are loaded.
Dispatches 'comfygit:workflow-loaded' custom event with workflow JSON
and missing node types for the upcoming missing resources popup feature.
Add comprehensive test coverage for the new /v2/comfygit/workflow/analyze-json
endpoint which will analyze workflow JSON directly without requiring the
workflow to be saved on disk.

Tests cover:
- Valid workflow JSON analysis with categorized results
- Default name handling ('unsaved')
- Error handling for missing/empty workflow data
- Error handling for invalid/malformed JSON
- Response format matching existing /workflow/{name}/analyze endpoint
- Subgraph support (ComfyUI v1.24.3+)
- Model reference extraction from node properties.models
- Uninstalled package detection
- is_fully_resolved logic

All 12 tests fail as expected - endpoint implementation blocked on
core library bead cg-2ro (WorkflowDependencyParser refactor).
Add new endpoint for analyzing workflow JSON directly without requiring
the workflow to be saved on disk. This enables analysis of workflows
loaded in the browser before saving.

Endpoint: POST /v2/comfygit/workflow/analyze-json
Request body: { "workflow": <json>, "name": "optional_name" }

Features:
- Accepts raw workflow JSON in request body
- Uses WorkflowDependencyParser with Workflow object (core refactor cg-2ro)
- Returns response matching existing /workflow/{name}/analyze format exactly
- Handles empty workflows, invalid structure, missing data gracefully
- Correctly identifies uninstalled packages

Tests updated to use correct mocks for the new implementation.
…ception

Create Vue component that shows when a workflow is loaded with missing nodes/models:
- Analyzes workflow via /v2/comfygit/workflow/analyze-json endpoint
- Displays missing nodes with package suggestions (max 5 with overflow)
- Displays missing models with download availability indicator
- Auto-dismisses if no issues found
- "Open ComfyGit Panel" button opens panel to workflows view
- Styled consistently with existing ComfyGit UI (BaseModal, BaseButton)

Also adds global listener for 'comfygit:open-panel' event.

Implements: cgm-z5o.3
- Update MissingResourcesPopup to listen for 'comfygit:workflow-loaded' events
- Replace showMissingResourcesPopup with mountMissingResourcesPopup pattern
- Mount popup once at startup instead of on-demand
- Component now dispatches 'comfygit:open-panel' event for panel integration
- Complete end-to-end flow: workflow load → analysis → popup → panel
- Update analyze-json endpoint to use new core library API (Workflow.from_json)
  instead of temp file workaround
- Disable ShowMissingModelsWarning and ShowMissingNodesWarning settings in
  beforeConfigureGraph hook so ComfyGit's popup is the only one shown
- Add legacy/ to gitignore for cloned reference repos
…Popup

Transform popup from passive notification into actionable resolution interface:
- Show deduplicated packages instead of node-type mappings
- Add Install/Download buttons for individual items
- Add bulk Install All/Download All actions
- Add "Don't show again" checkbox with per-workflow localStorage persistence
- Separate "Unknown Nodes" section for unresolved registry entries
- Remove emojis from section headers
- Integrate with useModelDownloadQueue and useComfyGitService
- Fix model download URL extraction (download_source is string, not object)
- Rename queuedPackages → installedPackages for clarity
- Add restart notification toast matching Manager's UX style
- Listen for 'reconnected' event and call refreshComboInNodes()
- No page refresh needed - nodes refresh automatically after restart
- Auto-close toast after successful restart (3 second delay)
- Defer modal visibility until analysis completes to prevent flash on
  workflows with no issues
- Fix per-workflow hash to include node IDs, ensuring "don't show again"
  applies to specific workflows rather than all workflows with same node types
- Make checkbox bidirectional - unchecking now removes the dismiss state
- Add "Reset Dismissed Popups" button in UI Settings to clear all dismissals
Scores from core library can exceed 1.0 (for ranking purposes), causing
the frontend ConfidenceBadge to display nonsensical percentages like "128%".

Now normalizes scores to 0.0-1.0 range where the highest score becomes 1.0
and others scale proportionally.
After selecting a package option, marking optional, skipping, or selecting
a search result in the resolution modal, the view now auto-advances to the
next unresolved item. Arrow buttons remain visible for manual navigation
back to change previous selections.

Implements cgm-at2 and cgm-t9g.
Add [tool.uv.sources] to pyproject.toml so uv automatically uses the
local editable version of comfygit-core during development. This ensures
we always test against the latest core library changes without waiting
for PyPI releases.
Replace direct node install API calls with ComfyUI-Manager's queue API
to eliminate race conditions when installing multiple packages.

Changes:
- Add queueNodeInstall() to useComfyGitService.ts for Manager queue API
- Update MissingResourcesPopup to use queue-based installation
- Add WebSocket listeners for cm-task-started/cm-task-completed events
- Show proper UI states: Install → Queued → Installing → Installed/Failed
- Dispatch restart notification only after all installs complete
- Add CSS styles for queued, installing, and failed badge states
The Manager queue API requires repository URL and version info to
install packages. The backend was already resolving this data from
the registry but the serializer was discarding it.

Changes:
- Expand _serialize_resolved_node() to include repository and latest_version
- Expand _serialize_ambiguous_node() with same fields
- Update MissingPackage interface to include repository/latest_version
- Update installPackage() to pass full package data to queueNodeInstall
- Fix fetchApi() to handle empty responses (Manager queue returns 200 with no body)
crypto.randomUUID() only works in secure contexts (HTTPS/localhost).
ComfyUI often runs on plain HTTP, causing the function to be undefined.
Added a fallback that uses Math.random() when crypto.randomUUID is unavailable.
- Skip popup for saved workflows (path/filename present) - tracked in panel
- Replace per-workflow hash dismissal with single global toggle
- Remove "Open ComfyGit Panel" button from popup footer
- Add auto-dismiss when workflow is saved (comfygit:workflow-changed event)
- Settings UI now uses toggle instead of reset button

Closes: cgm-w21
Add 7 tests for new POST /v2/comfygit/workflow/is-saved endpoint:
- Success case: workflow matches saved file (is_saved=True)
- Success case: workflow doesn't match (is_saved=False)
- Normalization: ignores extra.ds viewport state
- Error handling: missing workflow field (400)
- Error handling: invalid JSON body (400)
- Error handling: workflow not a dict (400)
- Error handling: no environment (500)

Tests currently fail with 404 - endpoint not implemented yet.
Backend (cgm-kg0):
- Add POST /v2/comfygit/workflow/is-saved endpoint in workflows.py
- Compute xxhash of normalized workflow JSON (strips extra.ds viewport state)
- Cache disk workflow hashes, invalidate via file watcher
- Add xxhash dependency

File watcher:
- Add cache invalidation calls in on_modified, on_created, on_deleted
- Use lazy import to avoid circular dependencies

Frontend (cgm-38y):
- Update MissingResourcesPopup to use new is-saved endpoint
- Replace ineffective path/filename check with API call
- Skip popup for saved workflows (tracked in ComfyGit panel)
- Gracefully handle API errors (show popup as fallback)
Replace lambda with named function to satisfy ruff E731
…ests

The _serialize_resolved_node function now accesses package_data.versions
and package_data.repository. Update test mocks to include these attributes.
Prevents popup from appearing repeatedly for the same workflow within
a browser session. When popup is shown, workflow ID is added to an
in-memory Set. Subsequent loads of the same workflow skip the popup.

- Cleared on browser refresh (fresh session)
- Works independently of global disable setting
- Workflows without ID fall through to existing hash check
When pasting a file URL, the preselection could happen before
directories finished loading, causing auto-detect to fail.
Now we also trigger auto-detect when directories load.
- Alt+Shift+L: Open ComfyGit Panel
- Alt+Shift+K: Quick Commit (when in managed environment)

Shortcuts appear in Settings → Keyboard Shortcuts and can be
customized by users.
- Update test to expect masked civitai token (***1234)
- Add test for masked HF token when set
- Add test for null HF token when not set
- Add test for short token masking (****)
- Add test for POST HF token update
- Add test for POST HF token clear

These tests verify security requirement: never return full tokens in API responses.
Implementation:
- Add _mask_token() helper to show only last 4 chars (***xxxx)
- GET /v2/comfygit/config now returns masked tokens for both providers
- POST /v2/comfygit/config now accepts huggingface_token field
- Full tokens never exposed in API responses (security requirement)

Test updates:
- Fix existing tests to mock get_huggingface_token()
- All 23 config endpoint tests passing

Acceptance criteria met:
✓ GET returns masked HF token (***xxxx) if set
✓ GET returns masked CivitAI token (***xxxx) if set
✓ GET returns null for unset tokens
✓ POST with huggingface_token saves to config
✓ POST with huggingface_token: null clears token
✓ Full token never returned in API response
Add HuggingFace token configuration to WorkspaceSettingsContent.vue
with dirty tracking to prevent saving masked values. Both CivitAI
and HF tokens now use dirty flags to only send updates when user
explicitly modifies the field.

Changes:
- Add HuggingFace Token input field in API Credentials section
- Add dirty tracking refs (civitaiTokenDirty, hfTokenDirty)
- Update hasChanges computed to use dirty flags
- Update loadSettings to populate HF token and reset dirty flags
- Update saveSettings to conditionally send tokens based on dirty state
- Update resetSettings to reset HF token and dirty flags
- Add @input handlers to both token fields

Closes: cgm-yg1
Add reusable modal component for managing API tokens (HuggingFace, CivitAI) that
can be triggered from within the download modal. Provides inline token configuration
without navigating away from the download flow.

Features:
- Provider-specific UI (HuggingFace/CivitAI with icons and help links)
- Display masked current token if exists (***xxxx)
- Clear existing token with confirmation
- Add/replace token with validation
- Proper loading states for save/clear operations
- Emits events (saved/cleared) for parent component integration

Related: cgm-xha
- Add 'Configure Token' button in search header showing token status
- Display masked token (Token: ***xxxx) when configured
- Add auth error detection (401/403/authentication/unauthorized)
- Show 'Configure HuggingFace Token' button on auth errors
- Auto-retry search after saving token on auth error
- Load token status on component mount
- Add CSS layout for search header and error state
- Add null check before calling toLowerCase() on searchError
- Cache toLowerCase() result to avoid multiple calls
- Prevents runtime error when searchError is null/undefined
Replace server-side /workflow/is-saved endpoint with client-side approach
that polls workflowStore.activeWorkflow until its activeState.id matches
the incoming workflow's ID, then checks isPersisted. This avoids the
timing bug where activeWorkflow pointed to the previous workflow.

Also cleans up main.ts hooks: removes unused missingNodeTypes/timestamp
from the workflow-loaded event, simplifies pending workflow state.
Adds configurable crash retry logic (crash_retry_max, crash_retry_delay_s)
so transient failures like OOM kills are retried with a delay before giving up.
Existing extra_args bypass is tried first, then general retries kick in.
6 tests covering GET /v2/comfygit/environments/{name}:
- full detail response with workflows, nodes, models
- is_current flag for active/inactive environments
- 500 for non-managed workspace
- 404 for non-existent environment
- 500 for internal errors
GET /v2/comfygit/environments/{name} returns rich detail for a single
environment: workflow sync state (synced/new/modified/deleted), tracked
nodes with name/version/source, and missing models with filename,
category, workflow_names, criticality, and can_download fields.
…s modal

Replace static count rows with collapsible sections that show detailed
names, sync states, versions, and model criticality when expanded.
Fetches EnvironmentDetail from API on modal open with graceful fallback.
The list endpoint's node_count/model_count measure problems (missing,
extra, mismatches), not totals. The detail endpoint returns accurate
totals from env.list_nodes(). Prefer detail counts when loaded.
Derive created_at from first git commit in .cec repo and display
as a full timestamp (e.g. "Jan 29, 2026, 9:49 PM") instead of
the previous relative format. Remove unused last_used row.
Clear sessionStorage tab keys at module load so a page refresh
always opens the panel on the status tab, while close/reopen
within the same page still remembers the last tab.
The Unicode ℹ character rendered as an upside-down exclamation mark
in some browser/font configurations. Use the same inline SVG pattern
as InfoButton.vue for consistent cross-browser rendering.
Fetch actual commit details via get_version_history() instead of
returning an empty array. Uses rev_range for normal pushes and
limit-only for first push (no remote branch).
The [tool.uv.sources] entry pointed to a local dev path that
doesn't exist on end-user machines, causing uv sync failures.
@akatz-ai akatz-ai merged commit 1da4c7e into main Feb 3, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant